using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.IO;
using System.Drawing;

namespace TPDSFileIO
{
    public class ImageProcessingIO
    {
        public static string ScanImage( TPDSControl.Image image, TPDSConfig.TPDSConfig configfile )
        {
            Process barcodescanner = null;
            string arguments = String.Empty;
            try
            {
                string granularity = configfile.BarcodeGranularity.ToString();
                string confidence = configfile.BarcodeConfidence.ToString();
                string expectedDpi = configfile.ExpectedDpi.ToString(); 
                string bctypes = configfile.BarcodeType.ToString();
                string inputImage = Path.Combine(Path.GetDirectoryName(image.ImagesetFilepath), Path.GetFileName(image.Filename));


                
                ProcessStartInfo processinfo = new ProcessStartInfo();
                processinfo.FileName = configfile.EYMBCPath;
                arguments = "-granularity " + granularity + " -minconf " + confidence + " -bctypes " + bctypes + " -expdpi " + expectedDpi;
                arguments = arguments + " \"" + inputImage + "\"";
                processinfo.Arguments = arguments;
                processinfo.UseShellExecute = false;
                processinfo.RedirectStandardOutput = true;
                barcodescanner = Process.Start(processinfo);

                int sleepCount = 0;
                int sleepMax = configfile.ProcessKillDelay;
                while (!barcodescanner.HasExited)
                {
                    if (sleepCount > sleepMax)
                    {
                        if ((barcodescanner != null) && (!barcodescanner.HasExited))
                        {
                            barcodescanner.Kill();
                        }
                    }
                    Thread.Sleep(100);
                    sleepCount+=100;
                }

                string output = barcodescanner.StandardOutput.ReadToEnd();                
                //barcodescanner.WaitForExit();

                output = output.ToUpper();
                return GetBarcodeFromString(output);
            }
            finally
            {
                if ((barcodescanner != null) && (!barcodescanner.HasExited))
                {
                    barcodescanner.Kill();
                }
            }

        }

        private static string GetBarcodeFromString(string xmlresult)
        {
            int numOfBarcodesStartPosition = xmlresult.IndexOf("<NBCODES>");
            int numOfBarcodesEndPosition = xmlresult.IndexOf("</NBCODES>");
            string numOfBarcodes = String.Empty;
            string barcode = String.Empty;

            if ((numOfBarcodesStartPosition > -1) && (numOfBarcodesEndPosition > -1))
            {
                numOfBarcodes = xmlresult.Substring(numOfBarcodesStartPosition + 9, numOfBarcodesEndPosition - numOfBarcodesStartPosition -9);
                if (Convert.ToInt32(numOfBarcodes) > 0)
                {
                    int barcodesStartPosition = xmlresult.IndexOf("<RAWDATA>");
                    int barcodesEndPosition = xmlresult.IndexOf("</RAWDATA>");

                    if ((barcodesStartPosition > 0) && (barcodesEndPosition > 0))
                    {
                        barcode = xmlresult.Substring(barcodesStartPosition + 9, barcodesEndPosition - barcodesStartPosition - 9);
                    }
                }
            }
            return barcode;
        }

        public static void MoveImage(string sourcefilepath, string targetfilepath) 
        {
            FileInfo sourcefile = null;
            try
            {
                sourcefile = new FileInfo(sourcefilepath);
                if (!File.Exists(targetfilepath))
                {
                    sourcefile.MoveTo(targetfilepath);
                }
            }
            catch (Exception ex)
            {
                TPDSConfig.ErrorLog.WriteError(ex.Message, sourcefilepath + " || " + targetfilepath);
            }
        }

        public static string CreateThumbnail(string filepath, int maxdimension)
        {
            string thumbnailpath = String.Empty;
            Image resizedImage = null;
            try
            {
                thumbnailpath = Path.GetDirectoryName(filepath);
                string newfilename = Path.GetFileNameWithoutExtension(filepath) + "_thumb" + Path.GetExtension(filepath);
                thumbnailpath = Path.Combine(thumbnailpath, newfilename);

                resizedImage = InternalResizeImage(filepath, maxdimension);
                if (resizedImage != null) //image was not resized, or an error occured
                {
                    resizedImage.Save(thumbnailpath, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
                return thumbnailpath;
            }
            catch (Exception ex)
            {
                TPDSConfig.ErrorLog.WriteError(ex.Message, filepath);
            }
            finally
            {
                if (resizedImage != null)
                {
                    resizedImage.Dispose();
                    resizedImage = null;
                }
            }
            return null;
        }

        public static void ResizeImage(string filepath, int maxdimension)
        {
            Image resizedImage = null;
            try
            {
                
                resizedImage = InternalResizeImage(filepath, maxdimension);
                if (resizedImage != null) //image was not resized, or an error occured
                {
                    resizedImage.Save(filepath, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
            }
            catch (Exception ex)
            {
                TPDSConfig.ErrorLog.WriteError(ex.Message, filepath);
            }
            finally
            {
                if (resizedImage != null)
                {
                    resizedImage.Dispose();
                    resizedImage = null;
                }
            }
        }

        private static Image InternalResizeImage(string filepath, int maxdimension)
        {
            Image originalImage = null;
            Image newImage = null;
            int newWidth;
            int newHeight;
            try
            {
                originalImage = Image.FromFile(filepath);

                //test if image needs to be resized
                if ((originalImage.Width > maxdimension) || (originalImage.Height > maxdimension))
                {
                    if (originalImage.Width >= originalImage.Height)
                    {
                        newWidth = maxdimension;
                        newHeight = Convert.ToInt32(originalImage.Height * newWidth / originalImage.Width);
                    }
                    else
                    {
                        newHeight = maxdimension;
                        newWidth = Convert.ToInt32(originalImage.Width * newHeight / originalImage.Height);
                    }

                    newImage = originalImage.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero);
                    originalImage.Dispose();
                    return newImage;
                }
            }
            catch (Exception ex)
            {
                TPDSConfig.ErrorLog.WriteError(ex.Message, filepath);
            }
            finally
            {
                if (originalImage != null)
                {
                    originalImage.Dispose();
                    originalImage = null;
                }
            }
            return null;
        }

   /*     public void ResizeImage(string OriginalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider)
        {
            System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile);

            // Prevent using images internal thumbnail
            FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
            FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);

            if (OnlyResizeIfWider)
            {
                if (FullsizeImage.Width <= NewWidth)
                {
                    NewWidth = FullsizeImage.Width;
                }
            }

            int NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width;
            if (NewHeight > MaxHeight)
            {
                // Resize with height instead
                NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;
                NewHeight = MaxHeight;
            }

            System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);

            // Clear handle to original file so that we can overwrite it if necessary
            FullsizeImage.Dispose();

            // Save resized picture
            NewImage.Save(NewFile);
        }*/

        
    }
}
